//------------------------------------------------------------------------------
// <copyright file="ServiceNameConverter.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------

namespace System.ServiceProcess.Design
{
    using System.ServiceProcess;
    using System.ComponentModel;
    using System.Diagnostics;
    using System;
    using System.ComponentModel.Design.Serialization;
    using System.Reflection;
    using System.Collections;
    using System.Globalization;
    /// <summary>
    /// Converts a service name to a string and vice versa.  This converter is used by the service name property editor.
    /// </summary>
    internal class ServiceNameConverter : TypeConverter
    {
        private StandardValuesCollection values;
        private string previousMachineName;
        /// <summary>
        /// Gets a collection of standard values for the data type.  This converter always returns a collection containing the names of all installed services on the local machine.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }
        /// <summary>
        /// Converts the given object to the type of this converter.  This converter converts service names to strings.  If the given object is a string,
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                string text = ((string)value).Trim();
                return text;
            }
            return base.ConvertFrom(context, culture, value);
        }
        /// <summary>
        /// Converts the given value object to the specified type, using the specified context and culture information.  This converter always returns a string.  If the given
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            ServiceController owner = (context == null) ? null : context.Instance as ServiceController;
            string machineName = ".";
            if (owner != null)
                machineName = owner.MachineName;

            if (values == null || machineName != previousMachineName)
            {
                try
                {
                    ServiceController[] installedServices = ServiceController.GetServices(machineName);
                    string[] serviceNames = new string[installedServices.Length];
                    for (int i = 0; i < installedServices.Length; i++)
                    {
                        serviceNames[i] = installedServices[i].ServiceName;
                    }

                    values = new StandardValuesCollection(serviceNames);
                    previousMachineName = machineName;
                }
                catch
                {
                    //Do Nothing
                }
            }
            return values;
        }
        /// <summary>
        /// Gets a value indicating whether the list of standard values returned from the GetStandardValues method is an exclusive list.  This converter always returns false.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }
        /// <summary>
        /// Gets a value indicating whether this object supports the standard set of values returned by the GetStandardValues method.  This converter always returns true.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
    }
}
